package org.feng.common.util;

import com.google.gson.*;
import org.feng.util.TimeUtil;

import java.lang.reflect.Type;
import java.time.LocalDateTime;

/**
 * gson工具类
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2023年08月26日 15时00分
 */
public class GsonUtil {
    /**
     * 不会序列化空字段的Gson对象
     */
    private static final Gson GSON = new GsonBuilder()
            .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeJsonSerializer())
            .create();
    /**
     * 可以序列化空字段的Gson对象
     */
    private static final Gson GSON_WITH_NULL = new GsonBuilder()
            .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeJsonSerializer())
            .serializeNulls().create();

    private static final Gson GSON_WITH_DISABLE_HTML_ESCAPING = new GsonBuilder()
            .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeJsonSerializer())
            .disableHtmlEscaping().create();

    public static Gson gson() {
        return GSON;
    }

    /**
     * 转换对象为json字符串（不会序列化空字段）
     *
     * @param object 目标对象
     * @return 一个json字符串
     */
    public static String toJson(Object object) {
        return GSON.toJson(object);
    }

    /**
     * 转换对象为json字符串（可以序列化空字段）
     *
     * @param object 目标对象
     * @return 一个json字符串
     */
    public static String toJsonWithNull(Object object) {
        return GSON_WITH_NULL.toJson(object);
    }

    /**
     * 转换对象为json字符串（禁止html转义）
     *
     * @param object 目标对象
     * @return 一个json字符串
     */
    public static String toJsonWithDisableTtmlEscaping(Object object) {
        return GSON_WITH_DISABLE_HTML_ESCAPING.toJson(object);
    }

    public static <T> T fromJson(String jsonStr, Class<T> clazz) {
        return GSON.fromJson(jsonStr, clazz);
    }

    /**
     * 校验字符串是否是一个json格式
     * <br> 注意：{@code "{}"} 也是符合条件的json
     *
     * @param jsonStr 目标字符串
     * @return true表示目标是一个正确的json格式
     */
    public static boolean validateJson(String jsonStr) {
        JsonElement jsonElement;
        try {
            jsonElement = JsonParser.parseString(jsonStr);
        } catch (Exception e) {
            return false;
        }
        if (jsonElement == null) {
            return false;
        }
        return jsonElement.isJsonObject();
    }


    /**
     * 序列化LocalDateTime
     */
    private static class LocalDateTimeJsonSerializer implements JsonSerializer<LocalDateTime> {

        @Override
        public JsonElement serialize(LocalDateTime localDateTime, Type type, JsonSerializationContext jsonSerializationContext) {
            return new JsonPrimitive(TimeUtil.defaultFormat(localDateTime));
        }
    }
}
